﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace Cabal.Kernel.DataSet
{
    /// <summary>
    /// 提供最多7个优先级别的队列
    /// </summary>
    /// <typeparam name="Element">元素类型</typeparam>
    public class PriorityQueue7<Element>
    {
        public PriorityQueue7()
        {
            init(DefaultCapcity);
        }
        public PriorityQueue7(int capcity)
        {
            init(capcity);
        }

        Mutex Mutex_Operator = new Mutex();

        const int DefaultCapcity = 10;
        void init(int capcity)
        {
            q = new Queue<Element>[7];
            for (int i = 0; i < 7; i++)
            {
                q[i] = new Queue<Element>(capcity);
            }
        }

        Queue<Element>[] q;

        public void Enqueue(Element item,Priority7 priority)
        {
            q[(int)priority].Enqueue(item);
        }

        public Element Dequeue()
        {
            Mutex_Operator.WaitOne();

            Element result;
            for (int i = 0; i < 6; i++)
                if (q[i].Count > 0)
                {
                    result = q[i].Dequeue();
                    Mutex_Operator.ReleaseMutex();
                    return result;
                }

            result = q[(int)Priority7.Idle].Dequeue();

            Mutex_Operator.ReleaseMutex();
            return result;
        }
        public Element Dequeue(Priority7 priority)
        {
            Mutex_Operator.WaitOne();

            Element result = q[(int)priority].Dequeue();

            Mutex_Operator.ReleaseMutex();
            return result;
        }

        public Element Peek()
        {
            Mutex_Operator.WaitOne();

            Element result;
            for (int i = 0; i < 6; i++)
                if (q[i].Count > 0)
                {
                    result = q[i].Peek();
                    Mutex_Operator.ReleaseMutex();
                    return result;
                }

            result = q[(int)Priority7.Idle].Peek();

            Mutex_Operator.ReleaseMutex();
            return result;
        }
        public Element Peek(Priority7 priority)
        {
            Mutex_Operator.WaitOne();

            Element result = q[(int)priority].Peek();

            Mutex_Operator.ReleaseMutex();
            return result;
        }


        public int Count
        {
            get
            {
                Mutex_Operator.WaitOne();

                int tot = 0;
                foreach (Queue<Element> i in q)
                    tot += i.Count;

                Mutex_Operator.ReleaseMutex();
                return tot;
            }
        }
        public int GetCount(Priority7 priority)
        {
            return q[(int)priority].Count;
        }

        public void Clear()
        {
            Mutex_Operator.WaitOne();
            foreach (Queue<Element> i in q)
                i.Clear();
            Mutex_Operator.ReleaseMutex();
        }
        public void Clear(Priority7 priority)
        {
            q[(int)priority].Clear();
        }

        public bool Contans(Element item)
        {
            Mutex_Operator.WaitOne();

            foreach (Queue<Element> i in q)
                if (i.Contains(item))
                {
                    Mutex_Operator.ReleaseMutex();
                    return true;
                }

            Mutex_Operator.ReleaseMutex();
            return false;
        }
        public bool Contans(Element item, Priority7 priority)
        {
            return q[(int)priority].Contains(item);
        }

        public Element[] ToArray()
        {
            Mutex_Operator.WaitOne();

            Element[] array = new Element[Count];
            int ptr = 0;
            foreach (Queue<Element> i in q)
                foreach (Element j in i)
                    array[ptr++] = j;

            Mutex_Operator.ReleaseMutex();
            return array;
        }

    }

    /// <summary>
    /// 优先级别枚举
    /// </summary>
    public enum Priority7 : int
    {
        Special = 1,
        High = 2,
        Midlle = 3,
        Nomal = 4,
        Low = 5,
        Idle = 6
    }

}
